/**
 * cs340 Fatboy Mafia Team 
 */
package fatboy.communication;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.net.SocketException;


/**
 *	@author Ilya Vinogradov
 *	@ 23-jan-10 11:17 PM
 *
 *	ServerTread thread is spawned by the Server thread to address
 *	 the needs of the connected client, while Server continues
 *	 listening.
 */
public class ServerThread extends Thread{
	String printOut = "";
	/** Turns debugging comments on and off */
	
	/** Stores the socket object */
	private Socket socket = null;
	
	/** Indicates whether to accept more transmissions
	 * from the client or not
	 */
    private boolean communicating = true;
    
    /** 
     * Counter of the connections accepted by all threads
	 * (and, thus, commands received by Server and
	 * executed by any ServerThread).
	 */
    private static int commandCount = 0;
	
	/**
	 * ServerThread initialization constructor
	 */
	public ServerThread(Socket socket) {
		super("ServerThread");
		this.socket = socket;
		try {
			socket.setSoLinger(true, 100);
		} catch (SocketException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * Closes the thread's sockets.
	 * @throws IOException
	 */
	public void closeSocket() throws IOException{
		//socket.close();
	}
	
	/**
	 * ServerThread executable code. It's executed whenever
	 *  the thread is created and "start()" method is executed on it.
	 */
	public void run() {
		printOut +="A Client has contacted the Server!\n";
		
		try {
			
			//open the output stream through the socket (for response)
			ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
			//open the output stream through the socket (for response)
			ObjectInputStream in = new ObjectInputStream(socket.getInputStream());

		 //   while (communicating) {
				// Address the needs of the client
		    	Command command = (Command) in.readObject();
		    	
		    	//Entering the critical section ...
		    	printOut +=
		    			"\n------------------- INCOMMING TRANSMISSION "
		    			+ (++commandCount) + " ------------------\n";
		    	printOut +=
		    			"\tReceived a command from the client: \"" + command.toString() + "\"\n";
		    	
		    	//Were we need to check if the command was to add or to remove the node.
		    	// if yes, grab the semaphore
		    		//possibly: Broadcast "LOCK" to all the nodes (they will grab the semaphore on the "LOCK")
		    		//Do add or remove
		    		//possibly: Broadcast "Unlock" to all the nodes (they will release the semaphore on "UNLOCK")
		    	//
		    	//Do other commands
		    	
		    	
		    	Object returnValue = command.excecute();
		    	printOut +="\tExecuted command returned: \"" + returnValue + "\"\n";
		    	
		    	//if (returnValue != null) {
		    		printOut +="\tSending the result back to the client...\n";
		    		out.reset();
		    		out.writeObject(returnValue);
		    		out.flush();
		    	//}
		    	
		    	//Leaving the critical section ...

		    	communicating = false; //stop any additional communication with the client
		    	
		    	// Assistance is no longer needed
//		    }
		    out.close();
		    in.close();
		    this.closeSocket();
		    
		} catch (IOException e) {
			// TODO Auto-generated catch block
			printOut += e.toString();
			System.out.println(printOut);
			e.printStackTrace();
			printOut = "";
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			printOut += e.toString();
			System.out.println(printOut);
			e.printStackTrace();
			printOut = "";
		}
		//printOut +="Stop Thread now Please.";
		//System.out.println(printOut);
		return;

	}

}
